// Fill out your copyright notice in the Description page of Project Settings.


#include "Player/AuraPlayerState.h"

#include "AbilitySystem/AuraAbilitySystemComponent.h"
#include "AbilitySystem/AuraAttributeSet.h"
#include "Net/UnrealNetwork.h"

AAuraPlayerState::AAuraPlayerState()
{
	AbilitySystemComponent = CreateDefaultSubobject<UAuraAbilitySystemComponent>(
		TEXT("AbilitySystemComponent")
	);
	// ASC的OwnerActor的构造函数中创建`AttributeSet`会自动注册到其`ASC`
	// AttributeSet的复制由ASC管理
	AttributeSet = CreateDefaultSubobject<UAuraAttributeSet>(TEXT("AttributeSet"));

	// 设置能力系统组件的复制状态
	AbilitySystemComponent->SetIsReplicated(true);
	
	// 设置游戏玩法效果的复制模式为混合模式
	AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);

	// 设置网络更新频率为每秒100次
	NetUpdateFrequency = 100.f;
}

void AAuraPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	/**
	*  同步属性注册的宏经常使用的有三种：
	*1. DOREPLIFETIME
	*2. DOREPLIFETIME_CONDITION
	*3. DOREPLIFETIME_CONDITION_NOTIFY
	*它们三种是一次递进的，
	*第一种就是基础的注册宏，在服务器变化时，会同步所有的客户端，
	*第二种增加了CONDITION 也就是条件，条件的参数有多种，按需设置
	* 第三种增加了NOTIFY
	* 如果使用DOREPLIFETIME ，后面两项是有默认值的 CONDITION的默认值是COND_None，
	* NOTIFY的默认值是REPNOTIFY_OnChanged就是本地属性变动时，才会调用RepNotify函数
	 */
	DOREPLIFETIME(AAuraPlayerState, Level);
	DOREPLIFETIME(AAuraPlayerState, XP);
}

void AAuraPlayerState::AddToLevel(int32 InLevel)
{
	Level += InLevel;
	OnLevelChangedDelegate.Broadcast(Level);
}

void AAuraPlayerState::SetLevel(int32 InLevel)
{
	Level = InLevel;
	OnLevelChangedDelegate.Broadcast(Level);
}

void AAuraPlayerState::AddToXP(int32 InXP)
{
	XP += InXP;
	OnXPChangedDelegate.Broadcast(XP);
}

void AAuraPlayerState::SetXP(int32 InXP)
{
	XP = InXP;
	OnXPChangedDelegate.Broadcast(XP);
}


UAbilitySystemComponent* AAuraPlayerState::GetAbilitySystemComponent() const
{
	return AbilitySystemComponent;
}

UAttributeSet* AAuraPlayerState::GetAttributeSet() const
{
	return AttributeSet;
}

void AAuraPlayerState::OnRep_Level(int OldLevel)
{
	//上面修改委托只会在服务器触发，在此处设置是在服务器更新到客户端本地后触发
	OnLevelChangedDelegate.Broadcast(Level);
}

void AAuraPlayerState::OnRep_XP(int OldXP) {}
